package com.cgy.utils.net.http.stream;

import com.cgy.utils.net.http.config.RequestConfig;
import com.cgy.utils.net.http.enums.HttpMethod;
import com.cgy.utils.net.http.exception.IThrowableHandler;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

/**
 * 流式
 * @author CHTK
 */
public class OkHttpStream {

    private static final String APPLICATION_JSON = "application/json";

    private final OkHttpClient okHttpClient = new OkHttpClient();

    private String url;

    private FormBody.Builder formBody = new FormBody.Builder();

    private RequestBody requestBody;

    private List<Header> headers = new ArrayList<>();

    private HttpMethod method;

    private RequestConfig requestConfig = new RequestConfig();

    public OkHttpStream(HttpMethod method) {
        this.method = method;
    }

    /**
     * 设置 url
     * @param url
     * @return
     */
    public OkHttpStream url(final String url) {
        this.url = url;
        return this;
    }

    /**
     * 添加消息头部
     * @param headerName
     * @param headerValue
     * @return
     */
    public OkHttpStream addHeader(final String headerName, final String headerValue) {
        if(StringUtils.isNotBlank(headerName)) {
            Header header = new Header(headerName, headerValue);
            headers.add(header);
        }
        return this;
    }
    /**
     * 添加消息内容
     * @param bodyName
     * @param bodyValue
     * @return
     */
    public OkHttpStream addBody(final String bodyName, final String bodyValue) {
        if(StringUtils.isNotBlank(bodyName)) {
            formBody.add(bodyName, bodyValue);
        }
        return this;
    }
    /**
     * 添加消息内容
     * @param json
     * @return
     */
    public OkHttpStream addJson(final String json) {
        if(StringUtils.isNotBlank(json)) {
            requestBody = RequestBody.create(MediaType.parse(APPLICATION_JSON), json);
        }
        return this;
    }
    /**
     * 连接时间
     * @param connectTimeout
     * @return
     */
    public OkHttpStream connectTimeout(final long connectTimeout) {
        requestConfig.setConnectTimeout(connectTimeout);
        return this;
    }
    /**
     * 异常处理
     * @param iThrowableHandler
     * @return
     */
    public OkHttpStream throwable(final IThrowableHandler iThrowableHandler) {
        requestConfig.setThrowable(iThrowableHandler);
        return this;
    }
    /**
     * 读取时间
     * @param readTimeout
     * @return
     */
    public OkHttpStream readTimeout(final long readTimeout) {
        requestConfig.setReadTimeout(readTimeout);
        return this;
    }
    /**
     * 读取时间
     * @param interceptor
     * @return
     */
    public OkHttpStream log(final Interceptor interceptor) {
        requestConfig.setInterceptor(interceptor);
        return this;
    }

    /**
     * ssl
     * @return
     */
    public OkHttpStream sslFactory(final SSLSocketFactory sslSocketFactory) {
        requestConfig.setSslSocketFactory(null == sslSocketFactory ? createSSLSocketFactory() : sslSocketFactory);
        return this;
    }

    /**
     * 构建
     * @return
     */
    public OkHttpStreamBuilder build() {
        if(StringUtils.isNotBlank(url)) {
            Request.Builder request = new Request.Builder().url(this.url);
            if(!headers.isEmpty()) {
                for (Header header : headers) {
                    if(StringUtils.isNotBlank(header.getName())) {
                        request.addHeader(header.getName(), header.getValue());
                    }
                }
            }
            requestConfig.setFormBody(formBody);
            requestConfig.setRequestBody(requestBody);
            return new OkHttpStreamBuilder(method, requestConfig, request);
        }
        return null;
    }

    /**
     * 生成安全套接字工厂，用于https请求的证书跳过
     * @return
     */
    public SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }
        return ssfFactory;
    }
    /**
     * 用于信任所有证书
     */
    public class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    @Getter
    @Setter
    @AllArgsConstructor
    public static class Header {
        private String name;
        private String value;
    }
}
